/**************************************************************************
 *         Copyright(c) 2008 by Sunplus mMedia  Technology Co., Ltd.      *
 *                                                                        *
 *  This software is copyrighted by and is the property of Sunplus mMedia *
 *  Technology Co., Ltd. All rights are reserved by Sunplus mMedia Techno-*
 *  logy Co., Ltd. This software may only be used in accordance with the  *
 *  corresponding license agreement. Any unauthorized use, duplication,   *
 *  distribution, or disclosure of this software is expressly forbidden.  *
 *                                                                        *
 *  This Copyright notice "M U S T" not be removed or modified without    *
 *  prior written consent of Sunplus mMedia Technology  Co., Ltd.         *
 *                                                                        *
 *  Sunplus mMedia Technology Co., Ltd. reserves the right to modify this *
 *  software without notice.                                              *
 *                                                                        *
 *  Sunplus mMedia Technology Co., Ltd.                                   *
 *  19-1, Innovation First Road, Science-Based Industrial Park,           *
 *  Hsin-Chu, Taiwan, R.O.C.                                              *
 *                                                                        *
 *  Author: Ted Chiu                                                      *
 **************************************************************************/
#include "general.h"
#include "disp_api.h"
#include "panel.h"

#define	DEBUG	0
#define	DELAY_MORE	2
#define	LCM_16_BITS_ENABLE	0

UINT8 HAL_Wait(UINT32 WaitTime);

/* au sub LCM RGB444 8 bit 98x64 */
////AUO: H018IN03 1.8"TFT+1.1"CSTN Dual-Panel
#if	DEBUG==0
void H018IN03_11CSTN_Init(UINT8 mode) 
{
	UINT16 para[4];
	mode = mode;
	dispPreInit();
	XBYTE[0x2D92] = 0x03;	// A0 go high for standby mode, CS0 inactive(high)
	XBYTE[0x2028] = 48 - 1;	// Set LCM dispnxck freq (0:1x, 1:2x, 2:3x, 3:4x...)
	XBYTE[0x2029] = 0x00;	// Set LCM disp1xck freq (0:1x, 1:2x, 2:3x, 3:4x...)
	XBYTE[0x2D00] = 0x0a;               // tvdspmode LCM
	XBYTE[0X2D06] = 1;	//vsync width
	XBYTE[0X2D07] = 1;	//hsync width
	dispPnlVhSet(96+20-1, 64+300, 11, 3, 96+2, 64);
	XBYTE[0x2D90] = 2; 	// actpulse: XWR active width
	XBYTE[0x2D91] = 2;	// rcvpulse: XRD active width
	XBYTE[0X2D27] = 8;	//ups_ck_phase
	LCM_InitSet(8,LCM_RGB444);	// sub LCM
	XBYTE[0x2D8A] = 0;	//LCM_DATA_ALIGNED_NONE
	XBYTE[0x2D8B] = 1;	/* {R,G,B} */
printf("%s %d 44\n", __FILE__, (unsigned short)__LINE__);

	/* set LCM format */
	XBYTE[0x2D29] = 0x01;              // Update display registers
	XBYTE[0x2D25] = 0x01;              // Display controller enable

	/* send LCM cmd */
	XBYTE[0x2D85] = 0x01;              // LCM command mode enable
	XBYTE[0x2D92] = 0x00;              // A0 go low for command mode, CS0 active(low)

	//dispLcmWrite(0x0084, NULL, 0);
	dispLcmWrite(0x0094, NULL, 0);
	dispLcmWrite(0x00D1, NULL, 0);
	HAL_Wait(40*DELAY_MORE);	//delay 40ms
	para[0] = 0x0007;
	dispLcmWrite(0x0020, para, 1);
	HAL_Wait(40*DELAY_MORE);	//delay 40ms
	dispLcmWrite(0x00A7, NULL, 0);
	para[0] = 0x000D;
	para[1] = 0x0006;
	dispLcmWrite(0x0081, para, 2);

	para[0] = 0x0003;
	dispLcmWrite(0x00FB, para, 1);

	para[0] = 0x0000;
	para[1] = 0x000F;
	para[2] = 0x0000;
	dispLcmWrite(0x00CA, para, 3);

	para[0] = 0x0028;
	para[1] = 0x002C;
	para[2] = 0x0005;
	dispLcmWrite(0x00F7, para, 3);

	para[0] = 0x0008;
	para[1] = 0x0006;
	dispLcmWrite(0x00F2, para, 2);

	para[0] = 0x0000;
	para[1] = 0x0000;
	para[2] = 0x0002;
	dispLcmWrite(0x00BC, para, 3);

	para[0] = 0x0001;
	dispLcmWrite(0x00BB, para, 1);

	para[0] = 0x0001;
	para[1] = 0x0040;
	dispLcmWrite(0x00A8, para, 2);
	dispLcmWrite(0x00AF, NULL, 0);

	para[0] = 0x0000;
	para[1] = 0x0030;
	dispLcmWrite(0x0015, para, 2);

	para[0] = 0x0001;
	para[1] = 0x0040;
	dispLcmWrite(0x0075, para, 2);
	dispLcmWrite(0x005C, NULL, 0);

	//while((XBYTE[0x2DC8] & 0x08)==0);	//WR=digtv[11]=0x2DC8 bit3 (digtv[15:8])

	XBYTE[0x2D85] = 0x00;	// LCM command mode disable
	XBYTE[0x2D92] = 0x02;	// A0 go high for data mode, CS0 active(keep low)
	XBYTE[0x2D93] = 0x01;	// dmaflag
	XBYTE[0x2D25] = 0x01;	// Display controller enable
	XBYTE[0x27E4] = 0x02;	// Update display registers
}
#endif

#if	LCM_16_BITS_ENABLE
void H018IN03_18TFT_Init(UINT8 mode) 
{

	UINT16 para[4];
	mode = mode;
	dispPreInit();
	XBYTE[0x2D92] = 0x03;              // A0 go high for standby mode, CS0 inactive(high)
	XBYTE[0x2028] = 40 - 1;	// Set LCM dispnxck freq (0:1x, 1:2x, 2:3x, 3:4x...)
	XBYTE[0x2029] = 0x00;	// Set LCM disp1xck freq (0:1x, 1:2x, 2:3x, 3:4x...)
	XBYTE[0x2D00] = 0x0a;               // tvdspmode LCM
	XBYTE[0X2D06] = 1;	//vsync width
	XBYTE[0X2D07] = 1;	//hsync width
	dispPnlVhSet(128+20-1, 160+100, 10, 3, 128, 160);

	XBYTE[0x2D90] = 2; 	// actpulse: XWR active width
	XBYTE[0x2D91] = 2;	// rcvpulse: XRD active width
	XBYTE[0X2D27] = 8;	//ups_ck_phase
	LCM_InitSet(16,LCM_RGB565);	//MAIN LCM
	XBYTE[0x2D8A] = 0;	//LCM_DATA_ALIGNED_NONE
	XBYTE[0x2D8B] = 1;	/* {R,G,B} */

	/* set LCM format */
	XBYTE[0x2D29] = 0x01;              // Update display registers
	XBYTE[0x2D25] = 0x01;              // Display controller enable

	 /* send LCM cmd */
	XBYTE[0x2D85] = 0x01;              // LCM command mode enable
	XBYTE[0x2D92] = 0x00;              // A0 go low for command mode, CS0 active(low)

	HAL_Wait(20);	//20ms

	para[0] = 0x0004;
	dispLcmWrite(0x07, para, 1);

	para[0] = 0x0203;
	dispLcmWrite(0x0D, para, 1);

	para[0] = 0x1115;
	dispLcmWrite(0x0E, para, 1);

	HAL_Wait(20);	//20ms

	para[0] = 0x0113;
	dispLcmWrite(0x01, para, 1);

	para[0] = 0x0700;
	dispLcmWrite(0x02, para, 1);

	para[0] = 0x1230;
	dispLcmWrite(0x05, para, 1);

	para[0] = 0x0000;
	dispLcmWrite(0x06, para, 1);

	para[0] = 0x4000;
	dispLcmWrite(0x0B, para, 1);

	para[0] = 0x0003;
	dispLcmWrite(0x0C, para, 1);

	para[0] = 0x0488;
	dispLcmWrite(0x03, para, 1);

	para[0] = 0x0000;
	dispLcmWrite(0x04, para, 1);

	HAL_Wait(40);	//40ms

	para[0] = 0x3115;
	dispLcmWrite(0x0E, para, 1);

	para[0] = 0x0213;
	dispLcmWrite(0x0D, para, 1);

	para[0] = 0x0000;
	dispLcmWrite(0x21, para, 1);

	para[0] = 0x0000;
	dispLcmWrite(0x30, para, 1);

	para[0] = 0x0205;
	dispLcmWrite(0x31, para, 1);

	para[0] = 0x0202;
	dispLcmWrite(0x32, para, 1);

	para[0] = 0x0000;
	dispLcmWrite(0x33, para, 1);

	para[0] = 0x0504;
	dispLcmWrite(0x34, para, 1);

	para[0] = 0x0205;
	dispLcmWrite(0x35, para, 1);

	para[0] = 0x0707;
	dispLcmWrite(0x36, para, 1);

	para[0] = 0x0000;
	dispLcmWrite(0x37, para, 1);

	para[0] = 0x0000;
	dispLcmWrite(0x0F, para, 1);

	para[0] = 0x0000;
	dispLcmWrite(0x11, para, 1);

	para[0] = 0x9F00;
	dispLcmWrite(0x14, para, 1);

	para[0] = 0x0000;
	dispLcmWrite(0x15, para, 1);

	para[0] = 0x7F00;
	dispLcmWrite(0x16, para, 1);

	para[0] = 0x9F00;
	dispLcmWrite(0x17, para, 1);

	para[0] = 0x1000;
	dispLcmWrite(0x3A, para, 1);

	para[0] = 0x000B;
	dispLcmWrite(0x3B, para, 1);

	para[0] = 0x0005;
	dispLcmWrite(0x07, para, 1);

	HAL_Wait(20);	//20ms

	para[0] = 0x0025;
	dispLcmWrite(0x07, para, 1);

	para[0] = 0x0027;
	dispLcmWrite(0x07, para, 1);

	para[0] = 0x0037;
	dispLcmWrite(0x07, para, 1);

	para[0] = 0x0000;
	dispLcmWrite(0x21, para, 1);

	dispLcmWrite(0x22, para, 1);	//Command: 0x22 --> Start DMA data

	XBYTE[0x2D85] = 0x00;              // LCM command mode disable
	XBYTE[0x2D92] = 0x02;              // A0 go high for data mode, CS0 active(keep low)
	XBYTE[0x2D93] = 0x01;				// dmaflag
	XBYTE[0x2D25] = 0x01;	// Display controller enable
	XBYTE[0x27E4] = 0x02;	// Update display registers
}
#endif


#if	DEBUG

void LCMWR(UINT16 cmd, UINT16 lcmdata)
{
    UINT8 wr_sts;

    XBYTE[0x2D83] = cmd & 0xFF;       // LCM command low byte
    XBYTE[0x2D87] = cmd >> 8;         // LCM command high byte
    XBYTE[0x2D92] = 0x00;             // A0 low for command mode, CS0 active(go low)
    XBYTE[0x2D80] = 0x00;             // LCM write pulse

    wr_sts=0;
    while(wr_sts==0)
      wr_sts = XBYTE[0x2DC8] & 0x08;  // WR=digtv[11]=0x2DC8 bit3 (digtv[15:8])

    XBYTE[0x2D83] = lcmdata & 0xFF;   // LCM command low byte
    XBYTE[0x2D87] = lcmdata >> 8;     // LCM command high byte
    XBYTE[0x2D92] = 0x02;             // A0 high for data mode, CS0 active(keep low)
    XBYTE[0x2D80] = 0x00;             // LCM write pulse

    wr_sts=0;
    while(wr_sts==0)
      wr_sts = XBYTE[0x2DC8] & 0x08;  // WR=digtv[11]=0x2DC8 bit3 (digtv[15:8])

}

void LCMCMD(UINT16 cmd)
{
    UINT8 wr_sts;

    XBYTE[0x2D83] = cmd & 0xFF;       // LCM command low byte
    XBYTE[0x2D87] = cmd >> 8;         // LCM command high byte
    XBYTE[0x2D92] = 0x00;             // A0 low for command mode, CS0 active(go low)
    XBYTE[0x2D80] = 0x00;             // LCM write pulse

    wr_sts=0;
    while(wr_sts==0)
      wr_sts = XBYTE[0x2DC8] & 0x08;  // WR=digtv[11]=0x2DC8 bit3 (digtv[15:8])

}

void LCMDATA(UINT16 lcmdata)
{
    UINT8 wr_sts;

    XBYTE[0x2D83] = lcmdata & 0xFF;   // LCM command low byte
    XBYTE[0x2D87] = lcmdata >> 8;     // LCM command high byte
    XBYTE[0x2D92] = 0x02;             // A0 high for data mode, CS0 active(keep low)
    XBYTE[0x2D80] = 0x00;             // LCM write pulse

    wr_sts=0;
    while(wr_sts==0)
      wr_sts = XBYTE[0x2DC8] & 0x08;  // WR=digtv[11]=0x2DC8 bit3 (digtv[15:8])

}

void InitLCMs(void)    //AUO: H018IN03 1.8"TFT+1.1"CSTN Dual-Panel
{
      UINT8 wr_sts;
      UINT16 i;

	  LCMCMD(0x0094);
	  LCMCMD(0x00D1);

	  //40ms
      for(i=0;i<600;i++)
	     XBYTE[0x2De1] = 0x00;
      //  DELAY_1ms();


	  LCMWR(0x0020,0x0007);

	  //40ms
      for(i=0;i<600;i++)
	     XBYTE[0x2De1] = 0x00;
      //  DELAY_1ms();

	  LCMCMD(0x00A7);
	  LCMWR(0x0081,0x000D);
	  LCMDATA(0x0006);
	  LCMWR(0x00FB,0x0003);
	  LCMWR(0x00CA,0x0000);
	  LCMDATA(0x000F);
	  LCMDATA(0x0000);
	  LCMWR(0x00F7,0x0028);
	  LCMDATA(0x002C);
	  LCMDATA(0x0005);
	  LCMWR(0x00F2,0x0008);
	  LCMDATA(0x0006);
	  LCMWR(0x00BC,0x0000);
	  LCMDATA(0x0000);
	  LCMDATA(0x0002);
	  LCMWR(0x00BB,0x0001);

	  LCMWR(0x00A8,0x0001);
	  LCMDATA(0x0040);
	  LCMCMD(0x00AF);

	  LCMWR(0x0015,0x0000);
	  LCMDATA(0x0030);
	  LCMWR(0x0075,0x0001);
	  LCMDATA(0x0040);
	  LCMCMD(0x005C);

      wr_sts=0;
       while(wr_sts==0)
         wr_sts = XBYTE[0x2DC8] & 0x08;  // WR=digtv[11]=0x2DC8 bit3 (digtv[15:8])

}

void H018IN03_11CSTN_Init(UINT8 ptr) 	/* au sub LCM RGB444 8 bit 98x64 */
{
	dispPreInit();

     // sub LCM
	 XBYTE[0x2028] = 0x2f;				// Set LCM dispnxck freq (0:1x, 1:2x, 2:3x, 3:4x...)
     XBYTE[0x2029] = 0x02;              // Set LCM disp1xck freq (0:1x, 1:2x, 2:3x, 3:4x...)
	 XBYTE[0x2D8c] = 0x01;				// 1.5T mode

     XBYTE[0x2D92] = 0x03;              // A0 go high for standby mode, CS0 inactive(high)

     XBYTE[0x2D00] = 0x0a;              // tvdspmode LCM
     XBYTE[0x2D06] = 1;                 // vsyncw: 1
     XBYTE[0x2D07] = 1;                 // hsyncw: 1
	dispPnlVhSet(96+20-1, 64+300, 11, 3, 96+2, 64);

	 //HAL_DispScaleSet(320, 240, 100);

     XBYTE[0x2D22] = 0x22;              // osdsubsamp,	imgsubsamp
	 XBYTE[0x2D90] = 0x02;              // actpulse: XWR active width
     XBYTE[0x2D91] = 0x02;              // rcvpulse: XRD active width

	 /* set LCM format */
	 XBYTE[0x2D82] = 0x02;              // LCM data format: 0=RGB666, 1=RGB565, 2=RGB444, 3=RGB332
     XBYTE[0x2D84] = 0x00;              // [0]=h16bit: 0=8bit 1=16bit parallel
                                        // [1]=ditheren: dither enable
                                        // [2]=M68ctl0, [3]=M68ctl1
     XBYTE[0x2D88] = 0x00;              // [0]=RGB666 mode
     XBYTE[0x2D8B] = 0x01;              // [0]=packmode: 0:{BGR}, 1:{RGB}

	 XBYTE[0x2D29] = 0x01;              // Update display registers

	 XBYTE[0x2D25] = 0x01;              // Display controller enable

	 /* send LCM cmd */
	 XBYTE[0x2D85] = 0x01;              // LCM command mode enable
     XBYTE[0x2D92] = 0x00;              // A0 go low for command mode, CS0 active(low)

	 InitLCMs();

     XBYTE[0x2D85] = 0x00;              // LCM command mode disable
	 XBYTE[0x2D92] = 0x02;              // A0 go high for data mode, CS0 active(keep low)

	 XBYTE[0x2D93] = 0x01;				// dmaflag
	 HAL_Display_enable();
	 printf("Set LCM output\n");
}
#endif
